﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.IO;

namespace WoWTCG
{
    public class Card
    {
        public Card(string[] info, string set)
        {
            this.CardName = info[0];
            this.Set = FindEnumValue<Set>(set);
            this.Type = FindEnumValue<CardType>(info[1]);
            this.Supertype = FindEnumValue<CardSupertype>(info[2]);
            this.Subtype = FindEnumValue<CardSubtype>(info[3]);
            this.Race = FindEnumValue<Race>(info[4]);
            this.Class = FindEnumValue<Class>(info[5]);
            this.Professions = new List<Profession>();
            foreach (string profession in info[6].Split(',', '"'))
                if (profession.Trim() != "")
                    this.Professions.Add(FindEnumValue<Profession>(profession));
            this.Talent = FindEnumValue<Talent>(info[7].Replace(" ", ""));
            this.Faction = FindEnumValue<Faction>(info[8]);
            this.Keywords = info[9];
            this.RaceRestriction = FindEnumValue<Race>(info[10]);
            this.TalentRestriction = FindEnumValue<Talent>(info[11]);
            this.ProfessionRestriction = FindEnumValue<Profession>(info[12]);
            this.ClassRestriction = new List<Class>();
            foreach (string c in info[13].Split(',', '"'))
                if (c.Trim() != "")
                    this.ClassRestriction.Add(FindEnumValue<Class>(c));
            this.Cost = info[14];
            this.StrikeCost = info[15];
            this.Rules = info[16];
            this.Flavor = info[17];
            this.Attack = GetIntValue(info[18]);
            this.AttackType = FindEnumValue<AttackType>(info[19]);
            this.Health = this.MaxHealth = GetIntValue(info[20]);
            this.Defense = GetIntValue(info[21]);
            this.CardNumber = int.Parse(info[22]);
            this.Rarity = FindEnumValue<Rarity>(info[23]);
            string imagePath = "images/" + SetName() + "/" + FormatCardName(info[0]) + ".jpg";
            if (File.Exists(imagePath))
                this.Image = Image.FromFile(imagePath);
        }

        private string SetName()
        {
            switch (this.Set)
            {
                case Set.HeroesOfAzeroth:
                    return "hoa";
            }
            return "";
        }

        private string FormatCardName(string str)
        {
            return str.Trim().Replace(' ', '_').Replace("\'","").ToLower();
        }

        private int? GetIntValue(string val)
        {
            int outVal;
            if (int.TryParse(val, out outVal))
                return outVal;
            return null;
        }

        private T FindEnumValue<T>(string value)
        {
            if (Enum.IsDefined(typeof(T), value))
                return (T)Enum.Parse(typeof(T), value, true);
            else
                return default(T);
        }

        public Set Set
        { get; set; }

        public int CardNumber
        { get; set; }

        public CardType Type
        { get; set; }

        public Image Image
        { get; set; }

        public int SetNumber
        { get; set; }

        public string CardName
        { get; set; }

        public CardSupertype Supertype
        { get; set; }

        public CardSubtype Subtype
        { get; set; }

        public Race Race
        { get; set; }

        public Class Class
        { get; set; }

        public List<Profession> Professions
        { get; set; }

        public Talent Talent
        { get; set; }

        public string Keywords
        { get; set; }

        public Faction Faction
        { get; set; }

        public Race RaceRestriction
        { get; set; }

        public Talent TalentRestriction
        { get; set; }

        public Profession ProfessionRestriction
        { get; set; }

        public List<Class> ClassRestriction
        { get; set; }

        public string Cost
        { get; set; }

        public string StrikeCost
        { get; set; }

        public string Rules
        { get; set; }

        public string Flavor
        { get; set; }

        public int? Attack
        { get; set; }

        public AttackType AttackType
        { get; set; }

        public int? Health
        { get; set; }

        public int? MaxHealth
        { get; set; }

        public int? Defense
        { get; set; }

        public Rarity Rarity
        { get; set; }

        public string[] AsArray()
        {
            string[] values = new string[12];
            values[0] = this.CardNumber.ToString();
            values[1] = this.CardName;
            values[2] = EnumToString(this.Type.ToString());
            values[3] = EnumToString(this.Supertype.ToString());
            values[4] = EnumToString(this.Subtype.ToString());
            values[5] = EnumToString(this.Race.ToString());
            values[6] = EnumToString(this.Class.ToString());
            values[7] = this.Keywords;
            values[8] = EnumToString(this.Faction.ToString());
            values[9] = this.Cost;
            values[10] = this.Attack.ToString();
            values[11] = this.Health.ToString();
            return values;
        }

        private string EnumToString(string str)
        {
            if (str.Trim() == "Null")
                return "";
            return str;
        }
    }

    public enum Set
    {
        HeroesOfAzeroth,
    }

    public enum CardType
    {
        Ability,
        Ally,
        Armor,
        Hero,
        Item,
        Quest,
        Weapon,
    }

    public enum CardSupertype
    {
        Null,
        Instant,
        TwoHanded,
    }

    public enum CardSubtype
    {
        Null,
        Talent,
        Blessing,
        Combo,
        FinishingMove,
        Curse,
        Shout,
        Cloth,
        Leather,
        Mail,
        Plate,
        Shield,
        Bow,
        Axe,
        Staff,
        Dagger,
        Gun,
        Mace,
        Sword,
        Polearm,
    }

    public enum Race
    {
        Null,
        Dwarf,
        Gnome,
        NightElf,
        Human,
        Draenei,
        Undead,
        Troll,
        Orc,
        Tauren,
        BloodElf,
        Raptor,
        Cat,
        Bear,
        Wolf,
        Imp,
        Succubus,
        Infernal,
        Voidwalker,
        Dragonkin,
        Goblin,
        Turtle,
        Hippogryph,
    }

    public enum Class
    {
        Null,
        All,
        Priest,
        Warlock,
        Hunter,
        Paladin,
        Mage,
        Druid,
        Rogue,
        Warrior,
        Shaman,
    }

    public enum Profession
    {
        Enchanting,
        Tailoring,
        Jewelcrafting,
        Blacksmithing,
        Alchemy,
        Engineering,
        Leatherworking,
        Mining,
        Herbalism,
        Skinning,
    }

    public enum Talent
    {
        Null,
        Holy,
        Afflication,
        Feral,
        Fire,
        Frost,
        Marksmanship,
        Protection,
        Restoration,
        Arms,
        Elemental,
        Subtlety,
        Shadow,
        Demonology,
        BeastMastery,
    }

    public enum Faction
    {
        Null,
        Alliance,
        Horde,
        Neutral
    }

    public enum AttackType
    {
        Null,
        Arcane,
        Fire,
        Frost,
        Holy,
        Melee,
        Nature,
        Ranged,
        Shadow
    }

    public enum Rarity
    {
        Common,
        Uncommon,
        Rare,
        Epic
    }
}
